package com.learn.post_processor;

import com.learn.post_processor.beans.dao.UserDaoImpl;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.beans.factory.support.BeanDefinitionRegistryPostProcessor;
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.springframework.beans.factory.support.RootBeanDefinition;

public class BeanFactoryPostProcessorImpl implements BeanFactoryPostProcessor, BeanDefinitionRegistryPostProcessor {
    @Override
    public void postProcessBeanFactory(ConfigurableListableBeanFactory configurableListableBeanFactory) throws BeansException {
        System.out.println("BeanFactoryPostProcessor：（一次）beanDefinitionMap填充后，beanDefinitionMap遍历创建Bean实例对象前");
        
        // 修改某个BeanDefinition
        BeanDefinition updateBeanDefinition = configurableListableBeanFactory.getBeanDefinition("userDao");
        updateBeanDefinition.setBeanClassName("com.learn.post_processor.beans.service.UserServiceImpl");
        
        // 动态注册BeanDefinition（该处需要强转，另一种方式是实现BeanDefinitionRegistryPostProcessor接口）
        BeanDefinition newBeanDefinition = new RootBeanDefinition(UserDaoImpl.class);
        DefaultListableBeanFactory defaultListableBeanFactory = (DefaultListableBeanFactory) configurableListableBeanFactory;
        defaultListableBeanFactory.registerBeanDefinition("userDao(new)", newBeanDefinition);
    }
    
    @Override
    public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry beanDefinitionRegistry) throws BeansException {
        System.out.println("BeanDefinitionRegistryPostProcessor：继承BeanFactoryPostProcessor的接口，用于动态注册BeanDefinition");
        
        // 动态注册BeanDefinition：BeanDefinitionRegistryPostProcessor接口内的抽象函数
        BeanDefinition newBeanDefinition = new RootBeanDefinition(UserDaoImpl.class);
        beanDefinitionRegistry.registerBeanDefinition("userDao(new-interface)", newBeanDefinition);
    }
}
